package com.youyun56.gps.android.common;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import android.app.ActivityManager;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

import com.youyun56.gps.android.service.LocationUploadService;

public enum NetWorkHelper {

    instance;

    private final static String tag = NetWorkHelper.class.getName();
    private Uri uri = Uri.parse("content://telephony/carriers");

    public static Boolean isNetEnable(Context context) {
        ConnectivityManager con = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkinfo = con.getActiveNetworkInfo();
        if (networkinfo == null || !networkinfo.isAvailable()) {
            // 当前网络不可用
            Toast.makeText(context.getApplicationContext(), "请先连接Internet！", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    public static boolean isServiceRunning(Context context, String className) {
        boolean isRunning = false;
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> serviceList = activityManager.getRunningServices(Integer.MAX_VALUE);
        if (!(serviceList.size() > 0)) {
            return false;
        }
        for (int i = 0; i < serviceList.size(); i++) {
            if (serviceList.get(i).service.getClassName().equals(className) == true) {
                Log.i(className, className + " is running");
                isRunning = true;
                break;
            }
        }
        Log.i(tag, "service is not running?==" + isRunning);
        return isRunning;

    }

    public boolean setMobileDataEnabled(Context c, boolean enabled) {

        final TelephonyManager mTelManager;

        mTelManager = (TelephonyManager) c

        .getSystemService(Context.TELEPHONY_SERVICE);

        try {

            Method m = mTelManager.getClass()

            .getDeclaredMethod("getITelephony");

            m.setAccessible(true);

            Object telephony = m.invoke(mTelManager);

            m = telephony.getClass().getMethod(

            (enabled ? "enable" : "disable") + "DataConnectivity");

            m.invoke(telephony);

            return true;

        }
        catch (Exception e) {

            Log.e("NetCheck ", "cannot fake telephony", e);

            return false;

        }

    }

    public void openAPN(Context context) {
        List<APN> list = getAPNList(context);
        for (APN apn : list) {
            ContentValues cv = new ContentValues();
            cv.put("apn", APNMatchTools.matchAPN(apn.apn));
            cv.put("type", APNMatchTools.matchAPN(apn.type));
            context.getContentResolver().update(uri, cv, "_id=?", new String[] { apn.id });
        }
    }

    public void closeAPN(Context context) {
        List<APN> list = getAPNList(context);
        for (APN apn : list) {
            ContentValues cv = new ContentValues();
            cv.put("apn", APNMatchTools.matchAPN(apn.apn) + "mdev");
            cv.put("type", APNMatchTools.matchAPN(apn.type) + "mdev");
            context.getContentResolver().update(uri, cv, "_id=?", new String[] { apn.id });
        }
    }

    private List<APN> getAPNList(Context context) {
        String tag = "Main.getAPNList()";
        // current不为空表示可以使用的APN
        String projection[] = { "_id,apn,type,current" };
        Cursor cr = context.getContentResolver().query(uri, projection, null, null, null);
        List<APN> list = new ArrayList<APN>();
        while (cr != null && cr.moveToNext()) {
            Log.d(tag,
                    cr.getString(cr.getColumnIndex("_id")) + " " + cr.getString(cr.getColumnIndex("apn")) + " "
                            + cr.getString(cr.getColumnIndex("type")) + " " + cr.getString(cr.getColumnIndex("current")));
            APN a = new APN();
            a.id = cr.getString(cr.getColumnIndex("_id"));
            a.apn = cr.getString(cr.getColumnIndex("apn"));
            a.type = cr.getString(cr.getColumnIndex("type"));
            Log.i(tag, a.toString());
            list.add(a);
        }
        if (cr != null)
            cr.close();
        return list;
    }

    class APN {
        String id;
        String apn;
        String type;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("id: ").append(id).append(LocationUploadService.line);
            sb.append("apn: ").append(apn).append(LocationUploadService.line);
            sb.append("type: ").append(type).append(LocationUploadService.line);
            return sb.toString();
        }
    }

    static class APNMatchTools {

        public static String matchAPN(String currentName) {
            if ("".equals(currentName) || null == currentName) {
                return "";
            }
            currentName = currentName.toLowerCase();
            if (currentName.startsWith(APNNet.CMNET))
                return APNNet.CMNET;
            else if (currentName.startsWith(APNNet.CMWAP))
                return APNNet.CMWAP;
            else if (currentName.startsWith(APNNet.GNET_3))
                return APNNet.GNET_3;
            else if (currentName.startsWith(APNNet.GWAP_3))
                return APNNet.GWAP_3;
            else if (currentName.startsWith(APNNet.UNINET))
                return APNNet.UNINET;
            else if (currentName.startsWith(APNNet.UNIWAP))
                return APNNet.UNIWAP;
            else if (currentName.startsWith(APNNet.CTNET))
                return APNNet.CTNET;
            else if (currentName.startsWith(APNNet.CTWAP))
                return APNNet.CTWAP;
            else if (currentName.startsWith("default"))
                return "default";
            else
                return "";
            // return currentName.substring(0, currentName.length() -
            // SUFFIX.length());
        }
    }

    static class APNNet {
        /*
         * 中国移动cmwap
         */
        public static String CMWAP = "cmwap";
        /**
         * 中国移动cmnet
         */
        public static String CMNET = "cmnet";
        // 中国联通3GWAP设置 中国联通3G因特网设置 中国联通WAP设置 中国联通因特网设置
        // 3gwap 3gnet uniwap uninet
        /**
         * 3G wap 中国联通3gwap APN
         */
        public static String GWAP_3 = "3gwap";
        /**
         * 3G net 中国联通3gnet APN
         */
        public static String GNET_3 = "3gnet";
        /**
         * uni wap 中国联通uni wap APN
         */
        public static String UNIWAP = "uniwap";
        /**
         * uni net 中国联通uni net APN
         */
        public static String UNINET = "uninet";
        /**
         * u电信
         */
        public static String CTNET = "ctnet";
        /**
         * 电信
         */
        public static String CTWAP = "ctwap";
    }

    public static void setMobileNetEnable(Context context) {
        ConnectivityManager connService = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (null != connService) {
            try {
                Method setMobileDataEnabledMethod = connService.getClass().getDeclaredMethod("setMobileDataEnabled", boolean.class);
                if (null != setMobileDataEnabledMethod) {
                    setMobileDataEnabledMethod.invoke(connService, true);
                }
            }
            catch (Exception e) {
                Log.e(tag, e.getMessage(), e);
            }
        }
    }

    public static boolean invokeMethod(String methodName, Object[] arg, Context context) throws Exception {

        ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        Class ownerClass = mConnectivityManager.getClass();

        Class[] argsClass = null;
        if (arg != null) {
            argsClass = new Class[1];
            argsClass[0] = arg.getClass();
        }

        Method method = ownerClass.getMethod(methodName, argsClass);

        Boolean isOpen = (Boolean) method.invoke(mConnectivityManager, arg);

        return isOpen;
    }

    public static Object invokeBooleanArgMethod(String methodName, boolean value, Context context) throws Exception {

        ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        Class ownerClass = mConnectivityManager.getClass();

        Class[] argsClass = new Class[1];
        argsClass[0] = boolean.class;

        Method method = ownerClass.getMethod(methodName, argsClass);

        return method.invoke(mConnectivityManager, value);
    }

}
